Struts2运行流程
- ActionProxy是Action的一个代理类,也就是说Action的调用时通过ActionProxy实现的,其实就是调用了ActionProxy.execute()方法,而该方法又调用了ActionInvocation.invoke()方法
- ActonInvocation就是Action的调用者,ActonInvocation在Action的执行过程中,负责Interceptor、Action和Result等一系列元素的调度
- 拦截器的调用顺序是在struts-default.xml文件中的defaultStack中进行定义的
Params拦截器
Parameters拦截器将把表单字段映射到ValueStack栈的栈顶对象(此时栈顶对象即为Action)的各个属性中,如果某个字段在模型里没有匹配的属性,Param拦截器将尝试ValueStack栈的下一个对象。
把Action和Model隔开
Action作为Controller,应当与Model隔离开,这才是MVC设计模式。
如果Action类实现了ModelDriven接口,该拦截器将把ModelDriven接口的getModel()方法返回的对象置于栈顶。
Action实现ModelDriven接口后的运行流程:
先会执行ModelDrivenInterceptor的intercept方法
123456789101112131415161718192021222324252627282930public String intercept(ActionInvocation invocation) throws Exception {// 获取Action对象,即EmpolyeeAction对象,此时该Action已经实现了ModelDriven接口// public class EmployeeAction implements RequestAware, ModelDriven<Employee>Object action = invocation.getAction();// 判断Action是否是ModelDriven的实例if (action instanceof ModelDriven) {// 强制转换为ModelDriven类型ModelDriven modelDriven = (ModelDriven) action;// 获取值栈ValueStack stack = invocation.getStack();// 调用ModelDriven接口的getModel()方法,即调用EmployeeAction的getModel()方法/*@Overridepublic Employee getModel() {// TODO Auto-generated method stubemployee = new Employee();return employee;}*/Object model = modelDriven.getModel();if (model != null) {// 把getModel()方法的返回值压入到值栈的栈顶,实际压入的是EmployeeAction的employee成员变量stack.push(model);}if (refreshModelBeforeResult) {invocation.addPreResultListener(new RefreshModelBeforeResult(modelDriven, model));}}return invocation.invoke();}执行ParametersInterceptor的intercept方法:把请求参数的值赋给栈顶对象对应的属性,若栈顶对象没有对应的属性,则查询值栈中下一个对象对应的属性
注意:getModel()方法不能提供以下实现,的确会返回一个Employee对象到值栈的栈顶,但当前Action的employee成员变量却是null:
12345public Employee getModel() {// TODO Auto-generated method stubreturn new Employee();}